package websem.handlers;

import java.util.ArrayList;
import java.util.Map;

import websem.database.SPARQLRequest;

public class OntologyHandler {
	
	private static String REQUESTS_PREFIXES = "PREFIX : <http://ontologies.alwaysdata.net/space#>\r\nPREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>\r\nPREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>\r\n";

	/**
	 * Generate requests associated with every words from initial request, matched from ontology.
	 * @param request
	 * @return
	 */
	public static ArrayList<String> generateSubsumedWordsFromOntology(String word) {
		
		// Generate SPARQLRequest to get synonyms and associated words
		String sparqlRequest = OntologyHandler.generateSubsumedWordsSPARQLRequest(word);
		ArrayList<String> words = OntologyHandler.executeSPARQLRequest(sparqlRequest);
		
		
		return words;
	}
	
	/**
	 * Generate requests associated with every words from initial request, matched from ontology.
	 * @param request
	 * @return
	 */
	public static ArrayList<String> generateSynonymesWordsFromOntology(String word) {
		
		// Generate SPARQLRequest to get synonyms and associated words
		String sparqlRequest = OntologyHandler.generateAssociatedWordsSPARQLRequest(word);
		ArrayList<String> words = OntologyHandler.executeSPARQLRequest(sparqlRequest);
		
		return words;
	}
	
	/**
	 * Generate SPARQL request that get all children of a word
	 * @param word
	 * @return
	 */
	private static String generateSubsumedWordsSPARQLRequest(String word) {
		
		word = word.toLowerCase();
		
		if (word.length() > 6) {
			word = word.substring(0, 6);
		}
		
		//Request for synonyms
		String sparqlRequest = REQUESTS_PREFIXES + 
							"SELECT ?result " +
							"WHERE { " +
							"	?o rdfs:label ?label. " +
							"   ?x rdfs:subClassOf ?o." +
							"	?x rdfs:label ?result. " +
							"   FILTER (regex(?label, \"^" + word + "$\"))" +
							"}";
		
		return sparqlRequest;
	}

	/**
	 * Generate SPARQL request that get all synonyms of a word
	 * @param word
	 * @return
	 */
	private static String generateAssociatedWordsSPARQLRequest(String word) {
		
		word = word.toLowerCase();
		
		if (word.length() > 6) {
			word = word.substring(0, 6);
		}
		
		//Request for synonyms
		String sparqlRequest = REQUESTS_PREFIXES + 
							"SELECT ?result " +
							"WHERE { " +
							"	?o rdfs:label ?label. " +
							"	?o rdfs:label ?result. " +
							"   FILTER (regex(?label, \"^" + word + "$\"))" +
							"}";
		
		return sparqlRequest;
	}
	
	/**
	 * Execute SPARQL request
	 * @param request
	 * @return
	 */
	@SuppressWarnings("finally")
	private static ArrayList<String> executeSPARQLRequest(String request) {
		
		ArrayList<String> results = new ArrayList<String>();
		try {
			SPARQLRequest sparqlRequest = new SPARQLRequest(request);
			Iterable<Map<String, String>> requestResults = sparqlRequest.execute();
			if (requestResults != null) {
				for (Map<String, String> map : requestResults){
					for (String key : map.keySet()){
						
						// If a result contains more than one word
						if (map.get(key).contains(" ")) {
							String[] splitted_words = map.get(key).split(" ");
							
							// Split spaces and get relevants words
							for (String word : splitted_words) {
								if (!TermHandler.isInStopList(word)) {
									results.add(word);
								}
							}
						} else {
							results.add(map.get(key));
						}
					}
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			return results;
		}
	}
	
}
